package com.zhiyou100.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhiyou100.entity.Message;
import com.zhiyou100.entity.ResponseEntity;
import com.zhiyou100.entity.UserInfo;
import com.zhiyou100.mapper.UserInfoMapper;
import com.zhiyou100.service.inter.UserInfoService;
import com.zhiyou100.util.message.SendMessage;
import com.zhiyou100.util.reutil.ReUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.Serializable;
import java.sql.Struct;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 用户模块-用户详情表
 *
 * @author yang
 * @version 1.0.0
 * @date 2020-10-06 12:12
 */
@Service
public class UserInfoServiceImpl implements UserInfoService {
    @Autowired
    private UserInfoMapper mapper;

    @Override
    public List<UserInfo> selectPage(Page<?> page) {
        return mapper.selectPage(page);
    }

    @Override
    public int insert(UserInfo entity) {
        return mapper.insert(entity);
    }

    @Override
    public int deleteById(Serializable id) {
        return mapper.deleteById(id);
    }

    @Override
    public int deleteByMap(Map<String, Object> columnMap) {
        return mapper.deleteByMap(columnMap);
    }

    @Override
    public int delete(Wrapper<UserInfo> wrapper) {
        return mapper.delete(wrapper);
    }

    @Override
    public int deleteBatchIds(Collection<? extends Serializable> idList) {
        return mapper.deleteBatchIds(idList);
    }

    @Override
    public int updateById(UserInfo entity) {
        return mapper.updateById(entity);
    }

    @Override
    public int update(UserInfo entity, Wrapper<UserInfo> updateWrapper) {
        return mapper.update(entity, updateWrapper);
    }

    @Override
    public UserInfo selectById(Serializable id) {
        return mapper.selectById(id);
    }

    @Override
    public List<UserInfo> selectBatchIds(Collection<? extends Serializable> idList) {
        return mapper.selectBatchIds(idList);
    }

    @Override
    public List<UserInfo> selectByMap(Map<String, Object> columnMap) {
        return mapper.selectByMap(columnMap);
    }

    @Override
    public UserInfo selectOne(Wrapper<UserInfo> queryWrapper) {
        return mapper.selectOne(queryWrapper);
    }

    @Override
    public Integer selectCount(Wrapper<UserInfo> queryWrapper) {
        return mapper.selectCount(queryWrapper);
    }

    @Override
    public List<UserInfo> selectList(Wrapper<UserInfo> queryWrapper) {
        return mapper.selectList(queryWrapper);
    }

    @Override
    public List<Map<String, Object>> selectMaps(Wrapper<UserInfo> queryWrapper) {
        return mapper.selectMaps(queryWrapper);
    }

    @Override
    public List<Object> selectObjs(Wrapper<UserInfo> queryWrapper) {
        return mapper.selectObjs(queryWrapper);
    }

    @Override
    public <E extends IPage<UserInfo>> E selectPage(E page, Wrapper<UserInfo> queryWrapper) {
        return mapper.selectPage(page, queryWrapper);
    }

    @Override
    public <E extends IPage<Map<String, Object>>> E selectMapsPage(E page, Wrapper<UserInfo> queryWrapper) {
        return mapper.selectMapsPage(page, queryWrapper);
    }

    @Override
    public ResponseEntity<Object> sendMessage(String phone, HttpServletRequest request) {
        int maxPhoneLength = 11;
        if (ObjectUtil.isNull(phone) || StrUtil.isBlank(phone) || phone.length() > maxPhoneLength || !ReUtil.isMobile(phone)) {
            // 电话号码不合法
            return new ResponseEntity<>(500, "电话号码不合法", null);
        }
        final Message message = Message.builder()
                .phoneNumber(phone)
                // 发送六位数字验证码
                .code(RandomUtil.randomNumbers(6))
                .createTime(new Date())
                .build();
        // 发送
        SendMessage.sendMessage(message.getPhoneNumber(), message.getCode());
        // 放入 session 中，名字为 messageCode
        request.getSession().setAttribute("messageCode", message);
        return new ResponseEntity<>(200, "发送成功！", null);
    }

    @Override
    public ResponseEntity<Object> messageLogin(String phone, String code, HttpServletRequest request) {
        final HttpSession session = request.getSession();
        // 进入方法的时间
        final Date now = new Date();
        // 判断 手机号合理性
        int maxPhoneLength = 11;
        if (ObjectUtil.isNull(phone) || StrUtil.isBlank(phone) || phone.length() > maxPhoneLength || !ReUtil.isMobile(phone)) {
            // 电话号码 不合法
            return new ResponseEntity<>(500, "电话号码不合法", null);
        }
        int maxCodeLength = 6;
        if (ObjectUtil.isNull(code) || StrUtil.isBlank(code) || code.length() > maxCodeLength || !ReUtil.isCode(code)) {
            // 验证码 不合法
            return new ResponseEntity<>(500, "验证码不合法", null);
        }
        // 判断 验证码合理性
        // 从 Session 中取出
        final Object object = session.getAttribute("messageCode");
        if (ObjectUtil.isNull(object)) {
            // 域中啥也没有
            return new ResponseEntity<>(500, "没有发送验证码", null);
        }
        // 转型
        final Message messageCode = (Message) object;
        // 计算 进入短信登陆方法的时间 和 验证码创建的时间 之间的差（结果是绝对值）
        final long between = DateUtil.between(now, messageCode.getCreateTime(), DateUnit.SECOND);
        int effectiveTime = 60;
        if (between > effectiveTime) {
            // 大于 60 秒无效
            return new ResponseEntity<>(500, "验证码已经失效", null);
        }
        // 验证码有效
        if (!StrUtil.equals(code, messageCode.getCode())) {
            // 验证码不一致
            return new ResponseEntity<>(500, "验证码错误", null);
        }
        // 验证码一致
        if (!StrUtil.equals(phone, messageCode.getPhoneNumber())) {
            // 手机号码和验证码不一致
            return new ResponseEntity<>(500, "手机号码和验证码不一致", null);
        }
        // 手机号码和验证码都一致
        // 根据手机号从 userInfo 取出一个
        final UserInfo userPhoneNumber = mapper.selectByMap(Dict.create()
                .set("user_phone_number", messageCode.getPhoneNumber())).get(0);
        session.setAttribute("userInfo", userPhoneNumber);
        return new ResponseEntity<>(200, "登陆成功！", null);
    }

    @Override
    public ResponseEntity<Object> login(String username, String password, HttpServletRequest request) {
        if (ObjectUtil.isNull(username) || ObjectUtil.isNull(password) || StrUtil.isBlank(username) || StrUtil.isBlank(password)) {
            // 任意一个为空
            return new ResponseEntity<>(500, "用户名或者密码为空！！", null);
        }
        // 根据 用户名获取一个用户
        final UserInfo user = mapper.selectByMap(Dict.create()
                .set("user_name", username)).get(0);

        if (ObjectUtil.isNull(user)) {
            // user 为空，说明没有此用户名
            return new ResponseEntity<>(500, "没有此用户名！！", null);
        }
        if (user.getUserPassword().equals(password)) {
            // 密码相同，登陆成功, 放入 session 中
            request.getSession().setAttribute("userInfo", user);
            return new ResponseEntity<>(200, "登陆成功！", null);
        } else {
            return new ResponseEntity<>(500, "登陆失败，密码错误", null);
        }

    }

    @Override
    public ResponseEntity<Object> logout(HttpSession session) {
        // 清空 session
        session.invalidate();
        return new ResponseEntity<>(200, "退出登陆成功！", null);
    }
}
